package com.example.private_auto_install.ftpGIt;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.HiddenFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.log4j.Logger;

/**
 * 文件变化监听器
 * 在Apache的Commons-IO中有关于文件的监控功能的代码. 文件监控的原理如下：
 * 由文件监控类FileAlterationMonitor中的线程不停的扫描文件观察器FileAlterationObserver，
 * 如果有文件的变化，则根据相关的文件比较器，判断文件时新增，还是删除，还是更改。（默认为1000毫秒执行一次扫描）
 */
public class FileListener extends FileAlterationListenerAdaptor {

    public static Logger publishLogProcess = Logger.getLogger("publishLogProcess");
    /**
     * @描述 打jar包使用的目录 监控目录
     */
    private static String rootPath = "";

    private static String jsonPath = "";


    /**
     * 文件创建执行
     */
    public void onFileCreate(File file) {
//        log.info("[新建]:" + file.getAbsolutePath());
//        System.out.println("[新建]:" + file.getAbsolutePath());
        this.createJSONFile(file);
    }

    /**
     * 文件创建修改
     */
    public void onFileChange(File file) {
//        log.info("[修改]:" + file.getAbsolutePath());
//        System.out.println("[修改]:" + file.getAbsolutePath());
        this.createJSONFile(file);
    }

    /**
     * 文件删除
     */
    public void onFileDelete(File file) {
//        log.info("[删除]:" + file.getAbsolutePath());
//        System.out.println("[删除]:" + file.getAbsolutePath());
        this.createJSONFile(file);
    }

    /**
     * 目录创建
     */
    public void onDirectoryCreate(File directory) {
//        log.info("[新建]:" + directory.getAbsolutePath());
//        System.out.println("[新建]:" + directory.getAbsolutePath());
    }

    /**
     * 目录修改
     */
    public void onDirectoryChange(File directory) {
//        log.info("[修改]:" + directory.getAbsolutePath());
//        System.out.println("[修改]:" + directory.getAbsolutePath());
    }

    /**
     * 目录删除
     */
    public void onDirectoryDelete(File directory) {
//        log.info("[删除]:" + directory.getAbsolutePath());
        System.out.println();
    }

    public void onStart(FileAlterationObserver observer) {
        super.onStart(observer);
    }

    public void onStop(FileAlterationObserver observer) {
        super.onStop(observer);
    }


    public static void initConfig(String projectPath) {
        if (projectPath != null && projectPath.length() > 0) {
            projectPath = projectPath;
        } else {
            projectPath = UtilFile.getProjectPath();
            if (projectPath == null) {
                System.out.println("获取根目录失败");
                return;
            }
            // 然后获取它的上级目录
            projectPath = projectPath.substring(0, projectPath.lastIndexOf(File.separator));
        }

        rootPath = projectPath + File.separator + "resource" + File.separator + "assets";
        jsonPath = projectPath + File.separator + "resource";

        //测试地址
//        rootPath = "E:\\小学科学\\教科版项目代码\\science-jk-teacher\\science-jk-teacher\\resource\\assets";
//        jsonPath = "E:\\小学科学\\教科版项目代码\\science-jk-teacher\\science-jk-teacher\\resource";
    }

    /**
     * @描述 启动，入口函数
     * @Param args
     * @返回值 void
     * @创建人-时间 by - 2022/2/17
     */
    public static void main(String[] args) {
//        startMonitorFile("");
        FileListener lis = new FileListener();
        lis.restartCreateJSON(MainIndex.projectPath);
    }

    /**
     * 当git拉取下来代码后，遍历所有资源文件，然后重新生成所有的json文件
     * 修改方式。取消监听生成json文件，采用按当前文件生成json文件
     * 小学科学的规则
     *
     * @param projectPath
     */
    public boolean restartCreateJSON(String projectPath) {
        initConfig(projectPath);
        //需要生成json的子文件夹
        List<Map<String, String>> list = new ArrayList<>();

        list = addListPathAndJSON(rootPath + File.separator + "Grade_01_1", "default_01_01.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_01_2", "default_01_02.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_02_1", "default_02_01.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_02_2", "default_02_02.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_03_1", "default_03_01.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_03_2", "default_03_02.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_04_1", "default_04_01.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_04_2", "default_04_02.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_05_1", "default_05_01.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_05_2", "default_05_02.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_06_1", "default_06_01.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Grade_06_2", "default_06_02.res", list);
        list = addListPathAndJSON(rootPath + File.separator + "Panel", "default.res", list);

        for (Map<String, String> map : list) {
            // 子文件夹路径
            String sonFilePath = map.get("sonFilePath");
            // json的名称
            String jsonName = map.get("jsonName");
            boolean flag = this.pre_handle_file(sonFilePath, jsonName + ".json", jsonPath);
            if (flag) {
                publishLogProcess.info("文件-" + sonFilePath + File.separator + jsonName + ".json" + "生成成功");
            } else {
                publishLogProcess.error("文件-" + sonFilePath + File.separator + jsonName + ".json" + "生成失败");
            }
        }


        return true;
    }

    /**
     * 理化生的规则
     *
     * @param projectPath
     * @return
     */
    public boolean restartCreateJSON_PCB(String projectPath) {
        initConfig(projectPath);
        //需要生成json的子文件夹
        List<Map<String, String>> list = new ArrayList<>();
        list = addListPathAndJSON(rootPath, "default_chemistry_organic.res", list);

        for (Map<String, String> map : list) {
            // 子文件夹路径
            String sonFilePath = map.get("sonFilePath");
            // json的名称
            String jsonName = map.get("jsonName");
            boolean flag = this.pre_handle_file(sonFilePath, jsonName + ".json", jsonPath);
            if (flag) {
                publishLogProcess.info("文件-" + sonFilePath + File.separator + jsonName + ".json" + "生成成功");
            } else {
                publishLogProcess.error("文件-" + sonFilePath + File.separator + jsonName + ".json" + "生成失败");
            }
        }
        return true;
    }

    private static List<Map<String, String>> addListPathAndJSON(String path, String jsonName, List<Map<String, String>> list) {
        Map<String, String> map = new HashMap<>();
        map.put("sonFilePath", path);
        map.put("jsonName", jsonName);
        list.add(map);
        return list;
    }


    /**
     * 开始启动监听
     */
    public static void startMonitorFile(String projectPath) {
//        initConfig(projectPath);
//        System.out.println("监听地址为：" + rootPath);
//        System.out.println("json地址为：" + jsonPath);
//        // 监控目录
//        String rootDir = FileListener.rootPath;
//        // 轮询间隔 5 秒
//        long interval = TimeUnit.MILLISECONDS.toMillis(1);
//        // 创建过滤器
//        IOFileFilter directories = FileFilterUtils.and(
//                FileFilterUtils.directoryFileFilter(),
//                HiddenFileFilter.VISIBLE);
//        IOFileFilter files = FileFilterUtils.and(
//                FileFilterUtils.fileFileFilter(),
//                FileFilterUtils.suffixFileFilter(".txt"));
//        IOFileFilter filter = FileFilterUtils.or(directories, files);
//        // 使用过滤器
////        FileAlterationObserver observer = new FileAlterationObserver(new File(rootDir), filter);
//        //不使用过滤器
//        FileAlterationObserver observer = new FileAlterationObserver(new File(rootDir));
//        observer.addListener(new FileListener());
//        //创建文件变化监听器
//        FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
//        // 开始监控
//        try {
//            monitor.start();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        System.out.println("监听启动成功");
    }

    /**
     * @描述 生成json文件
     * @Param
     * @返回值 void
     * @创建人-时间 by - 2022/2/17
     */
    public void createJSONFile(File file) {
        //已根目录为主，获取到根目录
        String jsonPath = this.jsonPath;

        // 监控目录
        String rootDir = this.rootPath;


        //根目录下，需要切分成13个文件夹，一个文件夹需要对应一个json文件
        //这里依据file的绝对路径是是否包含某一个文件夹名称。如果包含，则对应处理

//        File.separator;
        // 子文件夹路径
        String sonFilePath = "";
        // json的名称
        String jsonName = "";
        String changeFilePath = file.getAbsolutePath();
        String prePath = "assets" + File.separator;
        if (changeFilePath.contains(prePath + "Grade_01_1")) {
            sonFilePath = rootDir + File.separator + "Grade_01_1";
            jsonName = "default_01_01.res";
        } else if (changeFilePath.contains(prePath + "Grade_01_2")) {
            sonFilePath = rootDir + File.separator + "Grade_01_2";
            jsonName = "default_01_02.res";
        } else if (changeFilePath.contains(prePath + "Grade_02_1")) {
            sonFilePath = rootDir + File.separator + "Grade_02_1";
            jsonName = "default_02_01.res";
        } else if (changeFilePath.contains(prePath + "Grade_02_2")) {
            sonFilePath = rootDir + File.separator + "Grade_02_2";
            jsonName = "default_02_02.res";
        } else if (changeFilePath.contains(prePath + "Grade_03_1")) {
            sonFilePath = rootDir + File.separator + "Grade_03_1";
            jsonName = "default_03_01.res";
        } else if (changeFilePath.contains(prePath + "Grade_03_2")) {
            sonFilePath = rootDir + File.separator + "Grade_03_2";
            jsonName = "default_03_02.res";
        } else if (changeFilePath.contains(prePath + "Grade_04_1")) {
            sonFilePath = rootDir + File.separator + "Grade_04_1";
            jsonName = "default_04_01.res";
        } else if (changeFilePath.contains(prePath + "Grade_04_2")) {
            sonFilePath = rootDir + File.separator + "Grade_04_2";
            jsonName = "default_04_02.res";
        } else if (changeFilePath.contains(prePath + "Grade_05_1")) {
            sonFilePath = rootDir + File.separator + "Grade_05_1";
            jsonName = "default_05_01.res";
        } else if (changeFilePath.contains(prePath + "Grade_05_2")) {
            sonFilePath = rootDir + File.separator + "Grade_05_2";
            jsonName = "default_05_02.res";
        } else if (changeFilePath.contains(prePath + "Grade_06_1")) {
            sonFilePath = rootDir + File.separator + "Grade_06_1";
            jsonName = "default_06_01.res";
        } else if (changeFilePath.contains(prePath + "Grade_06_2")) {
            sonFilePath = rootDir + File.separator + "Grade_06_2";
            jsonName = "default_06_02.res";
        } else if (changeFilePath.contains(prePath + "Panel")) {
            sonFilePath = rootDir + File.separator + "Panel";
            jsonName = "default.res";
        } else if (changeFilePath.contains(prePath + "skin" + File.separator)) {
        } else if (changeFilePath.contains(File.separator + "test" + File.separator)) {
        } else {
            sonFilePath = "";
            jsonName = "";
        }
        if (sonFilePath.length() <= 0 || jsonName.length() <= 0) {
            return;
        }
        boolean flag = this.pre_handle_file(sonFilePath, jsonName + ".json", jsonPath);

        publishLogProcess.info("文件-" + sonFilePath + File.separator + jsonName + ".json" + "生成成功");
    }

    /**
     * 加载前置文件
     */
    public boolean pre_handle_file(String sonFilePath, String jsonName, String jsonPath) {
        List<File> listFiles = new ArrayList<>();
        File rootFile = new File(sonFilePath);
        UtilMonitor.findFileList(rootFile, listFiles);
        //  这里需要将预加载的文件也需要给过去
        File pre_rootFile = new File(rootPath + File.separator + "Panel");
        UtilMonitor.findFileList(pre_rootFile, listFiles);

        // 将项目中预先要加载的文件list获取到
        Map<String, String> pre_Files = createPreLoadList();

        //然后变量所有的文件，依据规则，生成listmap，
        boolean flag = this.writeJson(listFiles, jsonName, jsonPath, pre_Files);

        return flag;
    }

    /**
     * 提前加载的图片处理
     */
    public Map<String, String> createPreLoadList() {
        Map<String, String> map = new HashMap<>();

        List<File> pre_listFiles = new ArrayList<>();
        File pre_rootFile = new File(rootPath + File.separator + "Panel");
        UtilMonitor.findFileList(pre_rootFile, pre_listFiles);
        String pre_listFiles_str = "";
        for (int i = 0; i < pre_listFiles.size(); i++) {
            File item = pre_listFiles.get(i);
            //获取文件的后缀
            String extension = UtilFile.getFileExtension(item);
            //获取文件的名称
            String name = UtilFile.getFileName(item);
            pre_listFiles_str += name + "_" + extension + ",";
        }
        map.put("keys", pre_listFiles_str);
        map.put("name", "Panel");
        return map;
    }

    /**
     * @param list_pre_panel 预加载的列表
     * @描述
     * @Param listFiles 需要转换的所有文件
     * @Param: fileName 转换json的文件名称 带后缀
     * @Param: path  转换json的目录
     * @返回值 boolean
     * @创建人-时间 by - 2022/2/19
     */
    private boolean writeJson(List<File> listFiles, String fileName, String path, Map<String, String> pre_Files) {
//        final BufferedWriter bw;
//        boolean flag = true;
//        try {
//            Properties scale9gridConfig = UtilMonitor.getAllProperties("scale9grid");
//            //首先获取listFiles 中的文件信息，然后存储成list<map>
//            List<Map<String, String>> listMsg = new ArrayList<>();
//            for (int i = 0; i < listFiles.size(); i++) {
//                File item = listFiles.get(i);
//                //获取文件的路径
//                String absolutePath = item.getAbsolutePath();
//                //获取文件的后缀
//                String extension = UtilFile.getFileExtension(item);
//                //获取文件的名称
//                String name = UtilFile.getFileName(item);
////                System.out.println("路径" + getAbsolutePath);  //E:\idea_workspace\testFile\新建文本文档.txt
////                System.out.println("后缀" + extension); //txt
////                System.out.println("名称" + name); //新建文本文档
//
//                // 这里需要加一段逻辑，因精灵图的问题。判断是否是json后最，如果是json后缀，则判断同级目录下是否有对应的webp文件
////                如果有对应的webp文件，则解析json。如果json file有值，frames有值，则将frames中的key获取到，
//                String subkeys = this.getJSONSubkeys(extension, absolutePath);
//                Map<String, String> map = new HashMap<>();
//                map.put("url", absolutePath.replace(path + "\\", ""));
//                map.put("type", UtilFile.changeType(extension));
//                map.put("name", name + "_" + extension);
//                if (subkeys.length() > 0) {
//                    map.put("subkeys", subkeys);
//                    map.put("type", "sheet");
//                }
//                String scale9grid = scale9gridConfig.getProperty(name);
//                if (scale9grid != null && scale9grid.length() > 0) {
//                    map.put("scale9grid", scale9grid);
//                }
//                listMsg.add(map);
//            }
//
//            // 然后构建需要的json格式
//            Map<String, Object> RootMap = new HashMap<>();
//            List<Map<String, String>> temp = new ArrayList<>();
//            temp.add(pre_Files);
//            RootMap.put("groups", temp);
//            RootMap.put("resources", listMsg);
//
//            // 最后将rootMap 转换成json格式的，写入到文件中
//            JSONObject object = JSONObject.fromObject(RootMap);
//
//            File targeFile = new File(path, fileName);
//            boolean hasExists = targeFile.exists();
//            if (!hasExists) {
//                targeFile.createNewFile();
//            }
//            File f = new File(path, fileName);
//            bw = new BufferedWriter(new FileWriter(f, false));
//            bw.write(object.toString());
//
//            if (bw != null) {
//                bw.close();
//            }
//        } catch (Exception e) {
//            flag = false;
//            //            LOG.error("createFile(" + fileName + ") error:", e);
//            e.printStackTrace();
//        }
//        return flag;
        return true;
    }

    /**
     * @描述 因精灵图的问题。判断是否是json后最，如果是json后缀，则判断同级目录下是否有对应的webp文件
     * 如果有对应的webp文件，则解析json。如果json file有值，frames有值，则将frames中的key获取到，
     * @Param extension
     * @Param: absolutePath
     * @返回值 java.lang.String
     * @创建人-时间 by - 2022/2/22
     */
    private String getJSONSubkeys(String extension, String absolutePath) {
        String subkeys = "";

//        if ("json".equals(extension)) {
////                      判断同级目录下是否有对应的webp文件
////            String webpFilePath = absolutePath.substring(0, absolutePath.lastIndexOf(".")) + ".webp";
////            File webpFile = new File(webpFilePath);
////            if (webpFile.exists()) {
//            // 如果存在，则开始解析json文件
//            String json = UtilFile.readJsonFile(absolutePath).trim();
//            JSONObject obj = JSONObject.fromObject(json);
//            if (obj.get("file") != null && obj.getString("file").length() > 0
//                    && obj.getJSONObject("frames") != null) {
//                JSONObject framesObj = obj.getJSONObject("frames");
//                //获取obj的所有key值
//                Iterator keys = framesObj.keys();
//
//                while (keys.hasNext()) {
//                    String key = String.valueOf(keys.next());
//                    subkeys += key + ",";
//                }
//                // 去掉最后一个逗号
//                subkeys = subkeys.substring(0, subkeys.length() - 1);
//            }
////            }
//        }
        return subkeys;
    }
}